/********************************************************
 * ADO.NET 2.0 Data Provider for SQLite Version 3.X
 * Written by Robert Simpson (robert@blackcastlesoft.com)
 * 
 * Released to the public domain, use at your own risk!
 ********************************************************/

namespace EffiProz.Designer.Design
{
    using System;
    using System.Collections.Generic;
    using System.Text;
    using System.ComponentModel;
    using System.ComponentModel.Design;
    using System.Windows.Forms;
    using System.Drawing.Design;
    using System.Data;
    using System.Data.Common;
    using System.Globalization;

    internal class Column : IHaveConnection
    {
        private bool _allowNulls;
        private string _dataType = "";
        private string _defaultValue = "";
        private string _columnName = "";
        private string _origName = "";
        private DataGridViewRow _parent;
       // private Identity _identity;
        private Table _table;
        private bool _isDirty = false;

        [Browsable(false)]
        public bool IsDirty
        {
            get { return _isDirty; }
        }
      

        internal Column(Table table, DataGridViewRow row)
        {       
            _parent = row;
            _table = table as Table;
            //_identity = new Identity(this);
        }

        internal Column(DataRow row, Table source)
        {
            _table = source;
           // _identity = new Identity(this, row);

            _dataType = (row.IsNull("TYPE_NAME") == false) ? row["TYPE_NAME"].ToString() : String.Empty;
            _columnName = row["COLUMN_NAME"].ToString();
            _origName = _columnName;
            _allowNulls = (int)row["NULLABLE"] == 0 ? false : true;
            _defaultValue = (row.IsNull("COLUMN_DEF") == false) ? row["COLUMN_DEF"].ToString() : String.Empty;

            if ((_dataType == "VARCHAR" || _dataType == "LONGVARCHAR" || _dataType == "CHAR" ||
                _dataType == "CHARACTER" || _dataType == "BINARY" || _dataType == "VARBINARY") && row.IsNull("COLUMN_SIZE") == false)
            {
                long size = Convert.ToInt64(row["COLUMN_SIZE"]);
                if (size < short.MaxValue)
                    _dataType = string.Format(CultureInfo.InvariantCulture, "{0}({1})", _dataType, size);
            }
            else if (_dataType == "DECIMAL" && row.IsNull("COLUMN_SIZE") == false)
            {
                long size = Convert.ToInt64(row["COLUMN_SIZE"]);
                long scale = Convert.ToInt64(row["decimal_digits"]);
                if (size < short.MaxValue)
                {
                    _dataType = string.Format(CultureInfo.InvariantCulture, "{0}({1},{2})", _dataType, size, scale);
                }
            }
        }

        #region IHaveConnection Members

        [Browsable(false)]
        public ViewTableBase DesignTable
        {
            get { return _table; }
        }

        public DbConnection GetConnection()
        {
            return ((IHaveConnection)_table).GetConnection();
        }

        #endregion


        [Browsable(false)]
        internal Table Table
        {
            get { return _table; }
        }

        internal void Committed()
        {
            _origName = ColumnName;
            _isDirty = false;
        }

        internal DataGridViewRow Parent
        {
            get { return _parent; }
            set
            {
                _parent = value;
                _parent.Cells[0].Value = ColumnName;
                _parent.Cells[1].Value = DataType;
                _parent.Cells[2].Value = AllowNulls;
            }
        }

        internal void RefreshGrid()
        {
            if (_parent == null) return;
            _parent.DataGridView.Refresh();
        }

        internal void CellValueChanged(int rowIndex, int cellIndex)
        {
            if (_parent == null) return;
            if (rowIndex != _parent.Index) return;

            object value;

            if (_parent.Cells[cellIndex].IsInEditMode == true)
            {
                if (_parent.DataGridView.EditingControl != null)
                    value = ((IDataGridViewEditingControl)_parent.DataGridView.EditingControl).EditingControlFormattedValue;
                else
                    value = _parent.Cells[cellIndex].EditedFormattedValue;
            }
            else
                value = _parent.Cells[cellIndex].EditedFormattedValue;

            switch (cellIndex)
            {
                case 0:
                    ColumnName = value.ToString();
                    break;
                case 1:
                    DataType = value.ToString();
                    break;
                case 2:
                    try
                    {
                        AllowNulls = Convert.ToBoolean(value, CultureInfo.InvariantCulture);
                    }
                    catch
                    {
                    }
                    break;
            }
        }

        //[Category("Constraints")]
        //[Description("The identity constraints of the column")]
        //public virtual Identity Identity
        //{
        //    get { return _identity; }
        //}

        [Browsable(false)]
        public virtual string ColumnName
        {
            get { return _columnName; }
            set
            {
                value = value.Trim();
                if (value != _columnName)
                {
                    _columnName = value;
                    _isDirty = true;
                    _table.MakeDirty();
                }
            }
        }

        [Browsable(false)]
        public virtual string OriginalName
        {
            get { return _origName; }
        }

        [DefaultValue(false)]
        [DisplayName("Allow Nulls")]
        [Category("Constraints")]
        [Description("Specifies whether or not the column will allow NULL values.")]
        public virtual bool AllowNulls
        {
            get { return _allowNulls; }
            set
            {
                if (value != _allowNulls)
                {
                    _allowNulls = value;
                    _isDirty = true;
                    _table.MakeDirty();
                }
            }
        }

        [Browsable(false)]
        public virtual string DataType
        {
            get { return _dataType; }
            set
            {
                value = value.Trim();
                if (value != _dataType)
                {
                    _dataType = value;
                    _isDirty = true;
                    _table.MakeDirty();
                }
            }
        }

        [DisplayName("Default Value")]
        [Category("Constraints")]
        [Description("The default value to populate in the column when an explicit value is not specified.")]
        public virtual string DefaultValue
        {
            get { return _defaultValue; }
            set
            {
                value = value.Trim();

                if (value != _defaultValue)
                {
                    _defaultValue = value;
                    _isDirty = true;
                    _table.MakeDirty();
                }
            }
        }


        internal void GetAlterSql(List<String> sqlList)
        {
            if (String.IsNullOrEmpty(ColumnName) && String.IsNullOrEmpty(OriginalName))
            {               
                return;
            }
            else if (String.IsNullOrEmpty(ColumnName) && !String.IsNullOrEmpty(OriginalName))
            {
                sqlList.Add(String.Format("ALTER TABLE {0}.{1} DROP COLUMN {2};",
                     _table.Schema, _table.Name, OriginalName));
                return;
            }
            else if (String.IsNullOrEmpty(OriginalName)) // new column
            {
                StringBuilder builder = new StringBuilder();
                builder.AppendFormat("ALTER TABLE {0}.{1} ADD COLUMN {2}",
                     _table.Schema, _table.Name, ColumnName);

                if (String.IsNullOrEmpty(DataType) == false)
                    builder.AppendFormat(" {0}", DataType);


                if (String.IsNullOrEmpty(DefaultValue) == false)
                    builder.AppendFormat(" DEFAULT {0}", DefaultValue);

                if (AllowNulls == false)
                    builder.Append(" NOT NULL");

                builder.Append(" ;");
                sqlList.Add(builder.ToString());
            }
            else
            {     
                if(!String.Equals(OriginalName,ColumnName))
                {
                    sqlList.Add(String.Format(
                      "ALTER TABLE {0}.{1} ALTER COLUMN {2} RENAME TO {3};",
                        _table.Schema, _table.Name, OriginalName, ColumnName));
                }

                if (String.IsNullOrEmpty(DataType) == false)
                {                    
                   sqlList.Add(String.Format(
                       "ALTER TABLE {0}.{1} ALTER COLUMN {2} SET DATA TYPE {3};",
                         _table.Schema, _table.Name,ColumnName,DataType));                   
                }
                

                if (String.IsNullOrEmpty(DefaultValue) == false)
                {
                    sqlList.Add(String.Format(
                     "ALTER TABLE {0}.{1} ALTER COLUMN {2} SET DEFAULT {3} ;",
                       _table.Schema, _table.Name, ColumnName, DefaultValue));
                }
                else
                {
                    sqlList.Add(String.Format(
                    "ALTER TABLE {0}.{1} ALTER COLUMN {2} DROP DEFAULT ;",
                      _table.Schema, _table.Name, ColumnName));  
                }
                
                if (AllowNulls == false)
                {
                    sqlList.Add(String.Format(
                    "ALTER TABLE {0}.{1} ALTER COLUMN {2} SET NOT NULL  ;",
                      _table.Schema, _table.Name, ColumnName));
                }
                else
                {
                    sqlList.Add(String.Format(
                 "ALTER TABLE {0}.{1} ALTER COLUMN {2} SET NULL ;",
                   _table.Schema, _table.Name, ColumnName));   
                }
            }
        }


        internal void WriteSql(StringBuilder builder)
        {
                builder.AppendFormat("{0}", ColumnName);
                if (String.IsNullOrEmpty(DataType) == false)
                    builder.AppendFormat(" {0}", DataType);


                if (String.IsNullOrEmpty(DefaultValue) == false)
                    builder.AppendFormat(" DEFAULT {0}", DefaultValue);

                if (AllowNulls == false)
                    builder.Append(" NOT NULL");

                //if (_table.PrimaryKey.Columns.Count == 1 && String.Compare(_table.PrimaryKey.Columns[0].Column, ColumnName, StringComparison.OrdinalIgnoreCase) == 0)
                //{

                //    builder.Append(" PRIMARY KEY");                //}

        }

    }
}

